package com.sright.bcard.enterprise.biz.manager.impl;

import com.alibaba.fastjson.JSONObject;
import com.sright.bcard.common.service.share.dto.common.CheckImageDTO;
import com.sright.bcard.common.service.share.dto.common.CheckResultDTO;
import com.sright.bcard.common.service.share.dto.enterprise.AllAvatarDTO;
import com.sright.bcard.common.service.share.dto.enterprise.AllMaterialDTO;
import com.sright.bcard.common.service.share.dto.page.BetweenDateParamRequest;
import com.sright.bcard.common.service.share.dto.page.PageDTO;
import com.sright.bcard.common.service.share.dto.page.PageParamRequest;
import com.sright.bcard.common.service.share.dto.pager.Pager;
import com.sright.bcard.common.service.share.enums.BucketTypeEnum;
import com.sright.bcard.common.service.share.enums.CardTypeEnum;
import com.sright.bcard.common.service.share.exception.base.BusinessErrorException;
import com.sright.bcard.common.service.share.exception.code.BusinessCode;
import com.sright.bcard.common.service.share.utils.AliyunUitls;
import com.sright.bcard.common.service.share.utils.DataConvertUtils;
import com.sright.bcard.common.service.share.utils.DateTimeUtils;
import com.sright.bcard.common.share.service.ContentCheckService;
import com.sright.bcard.common.share.service.TranscodeService;
import com.sright.bcard.content.dal.dao.CardBaseInfoDAO;
import com.sright.bcard.content.dal.dao.MaterialDAO;
import com.sright.bcard.content.dal.dao.UserDAO;
import com.sright.bcard.content.dal.entity.CardBaseInfoDO;
import com.sright.bcard.content.dal.entity.MaterialDO;
import com.sright.bcard.content.dal.entity.UserDO;
import com.sright.bcard.enterprise.biz.manager.MaterialManager;
import com.sright.bcard.common.service.share.dto.enterprise.MaterialDTO;
import com.sright.bcard.common.service.share.enums.MaterialTypeEnum;
import com.sright.bcard.enterprise.share.response.MaterialResponse;
import com.sright.bcard.user.dal.dao.MemberDAO;
import com.sright.bcard.user.dal.entity.MemberDO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

@Component
@Slf4j
public class MaterialManagerImpl implements MaterialManager {

    @Autowired
    private MaterialDAO materialDAO;

    @Autowired
    private UserDAO userDAO;

    @Autowired
    private CardBaseInfoDAO cardBaseInfoDAO;

    @Autowired
    private TranscodeService transcodeService;

    @Autowired
    private ContentCheckService contentCheckService;

    @Autowired
    private MemberDAO memberDAO;

    @Override
    @Transactional
    public Long addMaterial(MaterialDTO materialDTO) {
        //判断素材类型
        String materialType = materialIsVideoOrImage(materialDTO.getType());
        // 获取企业id
        Long enterpriseId = materialDTO.getEnterpriseId();
        // DTO 转化 DO 对象
        MaterialDO materialDO = DataConvertUtils.
                convertDTO2DO(materialDTO, new MaterialDO());
        materialDO.setEnterpriseId(enterpriseId);
        materialDO.setCardType(CardTypeEnum.ENTERPRISE.getValue());
        materialDO.setCreatedAt(DateTimeUtils.getNowTime());
        materialDO.setUpdatedAt(DateTimeUtils.getNowTime());
        materialDO.setIsDefault(materialDTO.getIsDefault());
        materialDO.setIsCheck(1);

        if (materialType.equals("image")) {
            //阿里云图片审核
            CheckImageDTO checkImageDTO = checkImage(materialDTO.getFilePath(),null);
            materialDO.setNeedReview(checkImageDTO.getNeedReview());
            materialDO.setCheckResult(checkImageDTO.getCheckResult());
        }
        Long materialId = materialDAO.insertSelective(materialDO);

        //判断素材是视频则进行转码并提交阿里云审核
        if (materialType.equals("video")) {
            contentCheckService.submitSingleVideoCheck(materialId);
            transcodeService.materialTranscode(materialId,materialDTO.getFilePath(),materialDTO.getType());
        }

        return materialId;
    }

    /**
     * 查询素材是图片还是素材
     * @param type
     * @return
     */
    public String materialIsVideoOrImage(Integer type) {
        List<Integer> videoTypeList = Arrays.asList(MaterialTypeEnum.CARD_BACKGROUND_VEDIO.getValue(),
                MaterialTypeEnum.ENTERPRISE_PROPAGATE_VEDIO.getValue(),
                MaterialTypeEnum.ENDWAYS_VEDIO.getValue(),
                MaterialTypeEnum.HORIZONTAL_PICTURE.getValue());

        if (videoTypeList.contains(type)) {
            return "video";
        } else {
            return "image";
        }
    }

    /**
     * 进行阿里云图片审核
     * @param filePath
     * @return
     */
    public CheckImageDTO checkImage(String filePath,Long userId) {
        CheckResultDTO checkResultDTO = contentCheckService.singleImageCheck(filePath,userId);
        if (checkResultDTO == null) {
            throw new BusinessErrorException(BusinessCode.IMAGE_CHECK_ERROR);
        }
        CheckImageDTO checkImageDTO = new CheckImageDTO();
        if (checkResultDTO.getAd().equals("block") || checkResultDTO.getPorn().equals("block") || checkResultDTO.getTerrorism().equals("block")) {
            AliyunUitls.deleteSingleFile(BucketTypeEnum.IMAGE.getValue(),filePath);
            throw new BusinessErrorException(BusinessCode.IMAGE_CONTAIN_SENSITIVE_INFO);
        } else {
            if (checkResultDTO.getAd().equals("review") || checkResultDTO.getPorn().equals("review") || checkResultDTO.getTerrorism().equals("review")) {
                checkImageDTO.setNeedReview(1);
            } else {
                checkImageDTO.setNeedReview(0);
            }
            checkImageDTO.setCheckResult(JSONObject.toJSONString(checkResultDTO));
            return checkImageDTO;
        }
    }

    @Override
    public List<MaterialDO> list(MaterialDTO materialDTO) {
        // DTO 转化为 DO 对象
        MaterialDO materialDO = DataConvertUtils.
                convertDTO2DO(materialDTO, new MaterialDO());
        Long enterpriseId = materialDTO.getEnterpriseId();
        Integer type = materialDTO.getType();
        materialDO.setEnterpriseId(enterpriseId);
        materialDO.setType(type);
        materialDO.setCardType(CardTypeEnum.ENTERPRISE.getValue());
        List<MaterialDO> enterpriseMaterialDOS = materialDAO.selectByEnterpriseIdAndType(materialDO);
        if(CollectionUtils.isNotEmpty(enterpriseMaterialDOS)) {
            return enterpriseMaterialDOS;
        }
        return new ArrayList<>();
    }

    @Override
    public Integer editMaterial(MaterialDTO materialDTO) {
        // 查询原有的do对象
        MaterialDO sourceMaterialDO = materialDAO.selectById(materialDTO.getId());
        // DTO 转化为 DO 对象
        // 获取企业id
        Long enterpriseId = materialDTO.getEnterpriseId();
        MaterialDO enterpriseMaterialDO = DataConvertUtils.
                convertDTO2DO(materialDTO, sourceMaterialDO);
        enterpriseMaterialDO.setEnterpriseId(enterpriseId);
        enterpriseMaterialDO.setCardType(CardTypeEnum.ENTERPRISE.getValue());
        enterpriseMaterialDO.setCreatedAt(sourceMaterialDO.getCreatedAt());
        enterpriseMaterialDO.setUpdatedAt(DateTimeUtils.getNowTime());
        enterpriseMaterialDO.setIsDefault(materialDTO.getIsDefault());
        enterpriseMaterialDO.setBorderColor(materialDTO.getBorderColor());
        // 根据企业id查询素材列表
        List<MaterialDO> materialDOList = materialDAO.selectByEnterpriseId(materialDTO.getEnterpriseId());
        // 查询is_default的数量
        if(CollectionUtils.isNotEmpty(materialDOList) && materialDTO.getType() != null) {
            if(materialDTO.getType().intValue() == MaterialTypeEnum.CARD_BACKGROUND_VEDIO.getValue().intValue() ||
                    materialDTO.getType().intValue() == MaterialTypeEnum.PICTURE.getValue().intValue()) {
                List<MaterialDO> materialDOS = materialDOList.stream().filter(data -> data.getType().intValue() == MaterialTypeEnum.PICTURE.getValue().intValue() ||
                        data.getType().intValue() == MaterialTypeEnum.CARD_BACKGROUND_VEDIO.getValue().intValue()).collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(materialDOS)) {
                    List<MaterialDO> isDefaultMaterialDOs = materialDOS.stream().filter(data -> data.getIsDefault() == 1).collect(Collectors.toList());
                    if(CollectionUtils.isNotEmpty(isDefaultMaterialDOs) ) {
                        MaterialDO materialDO = isDefaultMaterialDOs.get(0);
                        // 如果被修改的默认值是1，则将materialDO的默认值修改为0
                        if(materialDTO.getIsDefault() == 1) {
                            materialDO.setIsDefault(0);
                            materialDAO.updateSelective(materialDO);
                        }
                    }
                }
            }
            if(materialDTO.getType().intValue() == MaterialTypeEnum.LOGO.getValue().intValue()) {
                List<MaterialDO> materialDOS = materialDOList.stream().filter(data -> data.getType().intValue() ==
                        MaterialTypeEnum.LOGO.getValue().intValue() && data.getIsDefault() == 1).collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(materialDOS) ) {
                    privateUpdate(materialDOS);
                }
            }
            if(materialDTO.getType().intValue() == MaterialTypeEnum.ENTERPRISE_PROPAGATE_VEDIO.getValue().intValue()) {
                List<MaterialDO> materialDOS = materialDOList.stream().filter(data -> data.getType().intValue() ==
                        MaterialTypeEnum.ENTERPRISE_PROPAGATE_VEDIO.getValue().intValue()).collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(materialDOS) ) {
                    privateUpdate(materialDOS);
                }
            }
            if(materialDTO.getType().intValue() == MaterialTypeEnum.PROPAGATE_VEDIO_BACKGROUND_PICATURE.getValue().intValue()) {
                List<MaterialDO> materialDOS = materialDOList.stream().filter(data -> data.getType().intValue() ==
                        MaterialTypeEnum.PROPAGATE_VEDIO_BACKGROUND_PICATURE.getValue().intValue()).collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(materialDOS) ) {
                    privateUpdate(materialDOS);
                }
            }
            if(materialDTO.getType().intValue() == MaterialTypeEnum.ENDWAYS_VEDIO.getValue().intValue()) {
                List<MaterialDO> materialDOS = materialDOList.stream().filter(data -> data.getType().intValue() ==
                        MaterialTypeEnum.ENDWAYS_VEDIO.getValue().intValue()).collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(materialDOS) ) {
                    privateUpdateEndwaysVedio(materialDOS);
                }
            }
            if(materialDTO.getType().intValue() == MaterialTypeEnum.LONG_PICTURE.getValue().intValue()) {
                List<MaterialDO> materialDOS = materialDOList.stream().filter(data -> data.getType().intValue() ==
                        MaterialTypeEnum.LONG_PICTURE.getValue().intValue()).collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(materialDOS) ) {
                    privateUpdate(materialDOS);
                }
            }
            if(materialDTO.getType().intValue() == MaterialTypeEnum.HORIZONTAL_PICTURE.getValue().intValue()) {
                List<MaterialDO> materialDOS = materialDOList.stream().filter(data -> data.getType().intValue() ==
                        MaterialTypeEnum.HORIZONTAL_PICTURE.getValue().intValue()).collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(materialDOS) ) {
                    privateUpdate(materialDOS);
                }
            }
            if(materialDTO.getType().intValue() == MaterialTypeEnum.SHARE_PICTURE.getValue().intValue()) {
                List<MaterialDO> materialDOS = materialDOList.stream().filter(data -> data.getType().intValue() ==
                        MaterialTypeEnum.SHARE_PICTURE.getValue().intValue()).collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(materialDOS) ) {
                    privateUpdate(materialDOS);
                }
            }
        }
        Boolean aBoolean = materialDAO.updateSelective(enterpriseMaterialDO);
        return aBoolean ? 1 : 0;
    }

    private void privateUpdateEndwaysVedio(List<MaterialDO> materialDOS) {

    }

    private void privateUpdate(List<MaterialDO> materialDOS) {
        materialDOS.forEach(materialDO -> {
            materialDO.setIsDefault(0);
            materialDAO.updateSelective(materialDO);
        });
    }

    @Override
    public Integer deleteMaterial(Long id) {
        Integer result = 0;
        MaterialDO materialDO = materialDAO.selectById(id);
        if (materialDO != null) {
            result = materialDAO.deleteById(id);
            //删除阿里云资源
            deleteOssSource(materialDO);
        }

        return result;
    }

    public void deleteOssSource(MaterialDO materialDO) {
        //判断素材类型
        String materialType = materialIsVideoOrImage(materialDO.getType());
        if (materialType.equals("video")) {
            //删除转码后的文件
            String[] strArray = materialDO.getFilePath().split("\\.");
            List<String> objectList = new LinkedList<>();
            objectList.add(materialDO.getFilePath());
            objectList.add(strArray[0] + "_540p.mp4");
            objectList.add(strArray[0] + "_720p.mp4");
            objectList.add(strArray[0] + "_1080p.mp4");
            AliyunUitls.deleteFileList(BucketTypeEnum.VIDEO.getValue(),objectList);
        } else {
            AliyunUitls.deleteSingleFile(BucketTypeEnum.IMAGE.getValue(),materialDO.getFilePath());
        }
    }

    @Override
    public List<MaterialDTO> personalMaterialList(MaterialDTO materialDTO) {
        // 获取用户id
        UserDO userDO = userDAO.selectById(materialDTO.getUserId());
        MaterialDO materialDO = new MaterialDO();
        materialDO.setUserId(userDO.getId());
        //获取当前正在使用的素材
        CardBaseInfoDO cardBaseInfoDO = cardBaseInfoDAO.selectByUserId(userDO.getId());
        String inUseMaterials = cardBaseInfoDO.getMaterialIds();
        List<Long> inUseMaterialList = new LinkedList<>();
        if (StringUtils.isNotEmpty(inUseMaterials)) {
            inUseMaterialList = Arrays.stream(inUseMaterials.split(",")).map(Long::parseLong).collect(Collectors.toList());
        }
        List<MaterialDO> materialDOS = materialDAO.selectByExample(materialDO);
        // DO 转 DTO
        if(CollectionUtils.isNotEmpty(materialDOS)) {
            List<MaterialDTO> materialDTOS = new ArrayList<>();
            DataConvertUtils.convertDOList2DTOList(materialDOS, materialDTOS, MaterialDTO.class);

            for (MaterialDTO materialDTO1 : materialDTOS) {
                if (inUseMaterialList.contains(materialDTO1.getId())) {
                    materialDTO1.setInUse(1);
                } else {
                    materialDTO1.setInUse(0);
                }
            }
            return materialDTOS;
        }
        return new ArrayList<>();
    }

    @Override
    public Long addPersonalMaterial(MaterialDTO materialDTO) {
        UserDO userDO = userDAO.selectById(materialDTO.getUserId());
        //判断用户现有素材数量
        Integer count = materialDAO.selectCountByUserIdAndType(userDO.getId(), materialDTO.getType());
        if (count > 20) {
            throw new BusinessErrorException(BusinessCode.MATERIAL_LIMIT_MAX);
        }

        //判断素材类型
        String materialType = materialIsVideoOrImage(materialDTO.getType());

        // DTO 转 DO
        MaterialDO materialDO = new MaterialDO();
        DataConvertUtils.convertDTO2DO(materialDTO, materialDO);
        if (materialType.equals("image")) {
            //阿里云图片审核
            CheckImageDTO checkImageDTO = checkImage(materialDTO.getFilePath(),materialDTO.getUserId());
            materialDO.setNeedReview(checkImageDTO.getNeedReview());
            materialDO.setCheckResult(checkImageDTO.getCheckResult());
        }
        materialDO.setUserId(userDO.getId());
        Long materialId = materialDAO.insertSelective(materialDO);
        //判断素材是视频则进行转码并提交阿里云审核
        if (materialType.equals("video")) {
            contentCheckService.submitSingleVideoCheck(materialId);
            transcodeService.materialTranscode(materialId,materialDTO.getFilePath(),materialDTO.getType());
        }

        return materialId;
    }

    @Override
    public Boolean editPersonalMaterial(List<Long> idList,Long userId) {
        CardBaseInfoDO cardBaseInfoDO = cardBaseInfoDAO.selectByUserId(userId);
        if (cardBaseInfoDO == null) {
            return false;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < idList.size(); i++) {
            sb.append(idList.get(i));
            if (i < idList.size() - 1) {
                sb.append(",");
            }
        }
        cardBaseInfoDO.setMaterialIds(sb.toString());
        return cardBaseInfoDAO.updateSelective(cardBaseInfoDO);
    }

    @Override
    public Integer deletePersonalMaterial(List<Long> ids) {
        final Integer[] count = {0};
        if(CollectionUtils.isNotEmpty(ids)) {
            ids.forEach(id -> {
                Integer integer = materialDAO.deleteById(id);
                count[0] = count[0] + integer;
            });
        }
        return count[0];
    }

    @Override
    public Pager<AllMaterialDTO> pageList(Integer contentType, BetweenDateParamRequest betweenDateParamRequest, PageParamRequest request, Integer needReview) {
        //card_type 1-个人 2-企业
        //content_type 1-视频 2-图片 3-分享图
        List<Integer> materialTypeList = new LinkedList<>();
        List<MaterialDO> list = new LinkedList<>();
        Integer count;
        if (contentType == 1) {
            materialTypeList.add(MaterialTypeEnum.CARD_BACKGROUND_VEDIO.getValue());
            materialTypeList.add(MaterialTypeEnum.ENTERPRISE_PROPAGATE_VEDIO.getValue());
            materialTypeList.add(MaterialTypeEnum.ENDWAYS_VEDIO.getValue());
            materialTypeList.add(MaterialTypeEnum.HORIZONTAL_PICTURE.getValue());
            count = materialDAO.count(materialTypeList, betweenDateParamRequest,needReview);
            list =  materialDAO.pageList(materialTypeList, betweenDateParamRequest, request,needReview);
        } else if (contentType == 2) {
            materialTypeList.add(MaterialTypeEnum.PICTURE.getValue());
            materialTypeList.add(MaterialTypeEnum.LOGO.getValue());
            materialTypeList.add(MaterialTypeEnum.PROPAGATE_VEDIO_BACKGROUND_PICATURE.getValue());
            materialTypeList.add(MaterialTypeEnum.LONG_PICTURE.getValue());
            count = materialDAO.count(materialTypeList, betweenDateParamRequest,needReview);
            list =  materialDAO.pageList(materialTypeList, betweenDateParamRequest, request,needReview);
        } else {
            //获取分享图
            count = materialDAO.countShareMaterial(betweenDateParamRequest,needReview);
            list =  materialDAO.shareMaterialList(betweenDateParamRequest, request,needReview);
        }

        List<AllMaterialDTO> result = new LinkedList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            for (MaterialDO materialDO : list) {
                AllMaterialDTO dto = new AllMaterialDTO();
                dto.setId(materialDO.getId());
                dto.setType(materialDO.getType());
                dto.setCover(materialDO.getCover());
                dto.setFilePath(materialDO.getFilePath());
                dto.setIsInteraction(materialDO.getIsInteraction());
                dto.setNeedReview(materialDO.getNeedReview());
                if (StringUtils.isNotEmpty(materialDO.getCheckResult())) {
                    dto.setCheckResult(JSONObject.parseObject(materialDO.getCheckResult(),CheckResultDTO.class));
                } else {
                    CheckResultDTO checkResultDTO = new CheckResultDTO();
                    checkResultDTO.setAd("pass");
                    checkResultDTO.setTerrorism("pass");
                    checkResultDTO.setPorn("pass");
                    dto.setCheckResult(checkResultDTO);
                }

                result.add(dto);
            }
        }

        return new Pager<>(request.getPageIndex(), request.getPageSize(), count, result);
    }

    @Override
    public Pager<AllAvatarDTO> avatarList(PageParamRequest paramRequest, Integer needReview) {
        Integer count = memberDAO.countAvatar(needReview);
        List<MemberDO> list =  memberDAO.avatarList(paramRequest, needReview);

        List<AllAvatarDTO> result = new LinkedList<>();
        for (MemberDO memberDO : list) {
            AllAvatarDTO dto = new AllAvatarDTO();
            dto.setId(memberDO.getId());
            dto.setFilePath(memberDO.getAvatarLocal());
            dto.setNeedReview(memberDO.getNeedReview());
            if (StringUtils.isNotEmpty(memberDO.getCheckResult())) {
                dto.setCheckResult(JSONObject.parseObject(memberDO.getCheckResult(),CheckResultDTO.class));
            } else {
                CheckResultDTO checkResultDTO = new CheckResultDTO();
                checkResultDTO.setAd("pass");
                checkResultDTO.setTerrorism("pass");
                checkResultDTO.setPorn("pass");
                dto.setCheckResult(checkResultDTO);
            }
            result.add(dto);
        }

        return new Pager<>(paramRequest.getPageIndex(), paramRequest.getPageSize(), count, result);
    }

    @Override
    public void deleteAvatar(Long id) {
        MemberDO memberDO = memberDAO.selectById(id);
        if (memberDO != null) {
            memberDO.setAvatarLocal("");
            memberDO.setNeedReview(0);
            memberDO.setCheckResult("");
            memberDAO.updateSelective(memberDO);
        }
    }

    @Override
    public PageDTO<MaterialResponse> page(MaterialDTO materialDTO) {
        PageDTO<MaterialResponse> pageDTO = new PageDTO<>();
        // DTO 转化为 DO 对象
        MaterialDO materialDO = DataConvertUtils.
                convertDTO2DO(materialDTO, new MaterialDO());
        Long enterpriseId = materialDTO.getEnterpriseId();
        Integer type = materialDTO.getType();
        materialDO.setEnterpriseId(enterpriseId);
        materialDO.setType(type);
        materialDO.setCardType(CardTypeEnum.ENTERPRISE.getValue());
        List<MaterialDO> enterpriseMaterialDOS = materialDAO.page(materialDO);
        Integer count = materialDAO.pageCount(materialDO);
        if(CollectionUtils.isNotEmpty(enterpriseMaterialDOS)) {
            // DO 转化为 DTO
            List<MaterialResponse> materialResponses = new ArrayList<>();
            DataConvertUtils.convertDOList2DTOList(enterpriseMaterialDOS, materialResponses, MaterialResponse.class);
            if(CollectionUtils.isNotEmpty(enterpriseMaterialDOS)) {
                pageDTO.setCount(count);
                pageDTO.setData(materialResponses);
                return pageDTO;
            }
        }
        return new PageDTO<>();
    }
}
